package org.mspring.mlog.security.user;

import org.mspring.mlog.entity.Node;
import org.mspring.mlog.entity.Resource;
import org.mspring.mlog.entity.Role;
import org.mspring.mlog.entity.User;
import org.mspring.mlog.security.service.NodeService;
import org.mspring.mlog.security.service.ResourceService;
import org.mspring.mlog.security.service.RoleService;
import org.mspring.mlog.security.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @author Gao Youbo
 * @since 2014-09-10 17:47:11
 */
@Component("userDetailService")
public class UserDetailServiceImpl implements UserDetailsService {

    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private NodeService nodeService;
    @Autowired
    private ResourceService resourceService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userService.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }
        Collection<GrantedAuthority> grantedAuths = obtionGrantedAuthorities(user);

        boolean enable = !user.getDeleted();
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;

        return new UserDetailsImpl(user.getUsername(), user.getPassword(), enable, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuths, user);
    }

    /**
     * 取得用户的权限
     *
     * @param user
     * @return
     */
    private Set<GrantedAuthority> obtionGrantedAuthorities(User user) {
        Set<GrantedAuthority> authSet = new HashSet<>();

        // 获取用户所有的角色
        List<Role> roles = roleService.listByUser(user.getId());

        for (Role role : roles) {
            // 获取角色所拥有的资源
            List<Resource> resources = resourceService.listByRole(role.getId());
            for (Resource res : resources) {
                authSet.add(new SimpleGrantedAuthority("resource_" + res.getId()));
            }

            List<Node> nodes = nodeService.listByRole(role.getId());
            Iterator<Node> it = nodes.iterator();
            while (it.hasNext()) {
                Node node = it.next();
                if (org.apache.commons.lang3.StringUtils.isNotBlank(node.getUrl())) {
                    authSet.add(new SimpleGrantedAuthority("node_" + node.getId()));
                }
            }
        }
        return authSet;
    }

}
